﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace WindowsGame1
{
    class Player : BaseObject
    {
        public bool m_bJumping; 
        public bool m_bDucking;
        public bool m_bDashing;
        public bool m_bIsOnLand;
        public bool m_bAttacking;
        public bool m_bIsHurt;
        public float m_fInvulnTimer;
        private GlobalContentManager GCM = GlobalContentManager.Instance;

        public List<Equip> m_lEquips = new List<Equip>();

        public Player()
        {
            // This is a comment
            // The below statement is true
            // The above statement is false
            // You just blew my mind
            m_ObjectType = OBJ_TYPE.OBJ_PLAYER;
            m_fDepth = 50;
            m_fInvulnTimer = 0.0f;

            
        }

        override public void Update(float deltaT , KeyboardState LastKeyState)
        {
            m_Position.Y += m_Velocity.Y * deltaT;
            m_Position.X += m_Velocity.X * deltaT * ((m_bJumping) ? 2.0f : 1) * ((m_bDashing && !m_bJumping) ? 2.0f : 1);

            if (m_Position.X < 32.0f)
                m_Position.X = 32.0f;
            if (m_Position.X > LevelManager.Instance.m_MapSize.X * LevelManager.Instance.m_TileSize.X - 32.0f)
                m_Position.X = LevelManager.Instance.m_MapSize.X * LevelManager.Instance.m_TileSize.X - 32.0f;

            //if (m_Position.Y > 600-1)
            //{
            //    m_Position.Y = 600;
            //    m_Velocity.Y = 0.0f;
            //    if (m_bJumping == true)
            //    {
            //        m_bJumping = false;
            //        m_bIsOnLand = true;
            //    }
            //}
            if (!m_bIsOnLand)
            {
                m_Velocity.Y += 4.11f;
                m_bJumping = true;
                m_bDucking = false;
            }
            else
            {
                m_Velocity.Y = 0.0f;
                m_bJumping = false;
            }

            if (m_Velocity.Y > 150)
            {
                m_Velocity.Y = 150;
            }

            if (m_bIsHurt == false)
            {
                if (Keyboard.GetState().IsKeyDown(Keys.Space) && LastKeyState.IsKeyUp(Keys.Space) && m_bJumping == false)
                {
                    m_Position.Y -= 25;
                    m_Velocity.Y = -96.0f;
                    m_bJumping = true;
                    m_bIsOnLand = false;
                    m_bDucking = false;
                }
                else if (Keyboard.GetState().IsKeyDown(Keys.LeftShift))
                {
                    m_bDashing = true;
                }
                else
                {
                    m_bDashing = false;
                }

                if (Keyboard.GetState().IsKeyDown(Keys.Left))
                {
                    m_bDucking = false;
                    if (LastKeyState.IsKeyDown(Keys.Down))
                        m_bAttacking = false;
                    m_Velocity.X = -25;
                    m_Direction = SpriteEffects.FlipHorizontally;
                }
                else if (Keyboard.GetState().IsKeyDown(Keys.Right))
                {
                    m_bDucking = false;
                    if (LastKeyState.IsKeyDown(Keys.Down))
                        m_bAttacking = false;
                    m_Velocity.X = 25;
                    m_Direction = SpriteEffects.None;
                }
                else if (!Keyboard.GetState().IsKeyDown(Keys.Right) && !Keyboard.GetState().IsKeyDown(Keys.Left))
                {
                    if (Keyboard.GetState().IsKeyDown(Keys.Down))
                    {
                        if (m_bAttacking == false)
                            m_bDucking = true;
                    }
                    else
                    {
                        m_bDucking = false;
                        if (LastKeyState.IsKeyDown(Keys.Down))
                            m_bAttacking = false;
                    }
                    m_Velocity.X *= 0.8f;
                    if ((m_Velocity.X <= 0.99f && m_Velocity.X > 0.0) || (m_Velocity.X >= -0.99f && m_Velocity.X < 0.0))
                    {
                        m_Velocity.X = 0.0f;
                    }
                }

                if (Keyboard.GetState().IsKeyDown(Keys.A) && LastKeyState.IsKeyUp(Keys.A) && m_bAttacking == false)
                {
                    m_bAttacking = true;
                    m_fFrame = 0.0f;
                }
                if (Keyboard.GetState().IsKeyDown(Keys.S) && LastKeyState.IsKeyUp(Keys.S))
                {
                    Random rand = new Random();
                    foreach (Equip p in m_lEquips)
                    {
                        p.m_cColor.B = (byte)(rand.Next(255));
                        p.m_cColor.G = (byte)(rand.Next(255));
                        p.m_cColor.R = (byte)(rand.Next(255));
                    }
                }
            }
            else
            {
                m_bDucking = false;
                m_bAttacking = false;
                m_bJumping = false;
                m_bIsOnLand = false;
                m_bDashing = false;
            }

            if (m_bAttacking == true)
            {
                m_AnimOrigin.X = 0;
                m_nMaxFrame = 3;
                m_AnimOrigin.Y = 256;
                if (m_bDucking == true && m_bJumping == false)
                {
                    m_nMaxFrame = 1;
                    m_AnimOrigin.X = 768;
                    m_AnimOrigin.Y = 0;
                }
            }
            else if (m_bJumping == true)
            {
                m_AnimOrigin.X = 256;
                m_nMaxFrame = 1;
                m_AnimOrigin.Y = 0;
            }
            else if (m_bDucking == true)
            {
                m_nMaxFrame = 1;
                m_AnimOrigin.X = 512;
                m_AnimOrigin.Y = 0;
                
            }
            else if (m_Velocity.X != 0.0f)
            {
                m_nMaxFrame = 4;
                m_AnimOrigin.X = 0;
                m_AnimOrigin.Y = 128;
            }
            else
            {
                m_nMaxFrame = 1;
                m_AnimOrigin.X = 0;
                m_AnimOrigin.Y = 0;
            }
            if (m_fInvulnTimer > 0.0f)
            {
                m_fInvulnTimer -= deltaT;
            }

            if (m_bAttacking == true)
            {
                m_fFrame += deltaT;
            }
            else
            {
                m_fFrame += deltaT * ((m_Velocity.X > 0.0f) ? m_Velocity.X : -m_Velocity.X) / 25.0f * ((m_bDashing && !m_bJumping) ? 1.5f : 1);
            }
            if (m_fFrame >= m_nMaxFrame)
            {
                m_fFrame = 0;
                if (m_bAttacking == true)
                {
                    m_bAttacking = false;
                }
            }
            m_bIsOnLand = false;
        }

        override public void Render(SpriteBatch spriteBatch, Camera cam)
        {
            byte SkinAlpha = 255;
            Color SkinColor = Color.White;
            if (m_fInvulnTimer > 0.0f)
            {
                SkinAlpha = 200;
                SkinColor.A = SkinAlpha;
            }
            if (m_bAttacking == false)
            {

                spriteBatch.Draw(m_Texture, new Rectangle((int)(m_Position.X*cam.m_fZoom - cam.m_Position.X), (int)((m_Position.Y * cam.m_fZoom - cam.m_Position.Y)), (int)(256 * cam.m_fZoom), (int)(128 * cam.m_fZoom)), new Rectangle(256 * (int)m_fFrame + (int)m_AnimOrigin.X, (int)m_AnimOrigin.Y, 256, 128), SkinColor, 0.0f, new Vector2(192 + (m_Direction == SpriteEffects.FlipHorizontally ? -128 : 0), 128), m_Direction, 0.0f);
                foreach (Equip p in m_lEquips)
                {
                    Color tempColor = p.m_cColor;
                    tempColor.A = SkinAlpha;
                    spriteBatch.Draw(p.m_Texture, new Rectangle((int)((m_Position.X * cam.m_fZoom - cam.m_Position.X)), (int)((m_Position.Y * cam.m_fZoom - cam.m_Position.Y)), (int)(256 * cam.m_fZoom), (int)(128 * cam.m_fZoom)), new Rectangle(256 * (int)m_fFrame + (int)m_AnimOrigin.X, (int)m_AnimOrigin.Y, 256, 128), tempColor, 0.0f, new Vector2(192 + (m_Direction == SpriteEffects.FlipHorizontally ? -128 : 0), 128), m_Direction, 0.0f);
                }
            }
            else
            {
                if (m_bDucking == true)
                {
                    spriteBatch.Draw(m_Texture, new Rectangle((int)((m_Position.X * cam.m_fZoom - cam.m_Position.X)), (int)((m_Position.Y * cam.m_fZoom - cam.m_Position.Y)), (int)(384 * cam.m_fZoom), (int)(128 * cam.m_fZoom)), new Rectangle(384 * (int)m_fFrame + (int)m_AnimOrigin.X, (int)m_AnimOrigin.Y, 384, 128), SkinColor, 0.0f, new Vector2(192, 128), m_Direction, 0.0f);
                    foreach (Equip p in m_lEquips)
                    {
                        Color tempColor = p.m_cColor;
                        tempColor.A = SkinAlpha;
                        spriteBatch.Draw(p.m_Texture, new Rectangle((int)((m_Position.X * cam.m_fZoom - cam.m_Position.X)), (int)((m_Position.Y * cam.m_fZoom - cam.m_Position.Y)), (int)(384 * cam.m_fZoom), (int)(128 * cam.m_fZoom)), new Rectangle(384 * (int)m_fFrame + (int)m_AnimOrigin.X, (int)m_AnimOrigin.Y, 384, 128), tempColor, 0.0f, new Vector2(192, 128), m_Direction, 0.0f);
                    }
                }
                else
                {
                    spriteBatch.Draw(m_Texture, new Rectangle((int)((m_Position.X * cam.m_fZoom - cam.m_Position.X)), (int)((m_Position.Y * cam.m_fZoom - cam.m_Position.Y)), (int)(384 * cam.m_fZoom), (int)(256 * cam.m_fZoom)), new Rectangle(384 * (int)m_fFrame + (int)m_AnimOrigin.X, (int)m_AnimOrigin.Y, 384, 256), SkinColor, 0.0f, new Vector2(192, 256), m_Direction, 0.0f);
                    foreach (Equip p in m_lEquips)
                    {
                        Color tempColor = p.m_cColor;
                        tempColor.A = SkinAlpha;
                        spriteBatch.Draw(p.m_Texture, new Rectangle((int)((m_Position.X * cam.m_fZoom - cam.m_Position.X)), (int)((m_Position.Y * cam.m_fZoom - cam.m_Position.Y)), (int)(384 * cam.m_fZoom), (int)(256 * cam.m_fZoom)), new Rectangle(384 * (int)m_fFrame + (int)m_AnimOrigin.X, (int)m_AnimOrigin.Y, 384, 256), tempColor, 0.0f, new Vector2(192, 256), m_Direction, 0.0f);
                    }
                }
            }
            
        }

        public override void CollisionResponse(BaseObject other)
        {
            if (other.m_ObjectType == OBJ_TYPE.OBJ_SCENEOBJECT)
            {
                Rectangle myFeet = new Rectangle((int)m_Position.X - 16, (int)m_Position.Y - 28, 32, 28);
                Rectangle myRect = new Rectangle((int)m_Position.X - 32, (int)m_Position.Y - 128, 64, 100);
                Rectangle rockRect = new Rectangle((int)other.m_Position.X - 64, (int)other.m_Position.Y - 128, 128, 128);

                if (myFeet.Intersects(rockRect))
                {
                    Rectangle collRect = Rectangle.Intersect(myFeet, rockRect);
                    if (m_Velocity.Y >= 0.0)
                    {
                        m_Position.Y += (collRect.Height - 1) * Math.Sign(m_Position.Y - other.m_Position.Y);
                        //m_Velocity.Y = 0.0f;
                        m_bJumping = false;
                        m_bIsOnLand = true;
                        m_bIsHurt = false;
                    }
                }
                else if (myRect.Intersects(rockRect))
                {
                    Rectangle collRect = Rectangle.Intersect(myRect, rockRect);
                    Vector2 Angle = new Vector2(myRect.Center.Y - rockRect.Center.Y, myRect.X - rockRect.X);
                    if (collRect.Width > collRect.Height)
                    {
                        m_Position.Y += (collRect.Height + 1) * Math.Sign(m_Position.Y - other.m_Position.Y);
                        if (m_Velocity.Y < 0.0f)
                            m_Velocity.Y = 0.0f;
                    }
                    else
                        m_Position.X += (collRect.Width + 1) * Math.Sign(m_Position.X - other.m_Position.X);
                }
            }
            else if (other.m_ObjectType == OBJ_TYPE.OBJ_TILE)
            {
                if (!LevelManager.Instance.m_TileProperties[((Tile)other).m_nTileID].m_bIsSolid)
                    return;

                Rectangle myFeet = new Rectangle((int)m_Position.X - 16, (int)m_Position.Y - 28, 32, 28);
                Rectangle myRect = new Rectangle((int)m_Position.X - 32, (int)m_Position.Y - 128, 64, 100);
                Rectangle tileRect = new Rectangle((int)other.m_Position.X, (int)other.m_Position.Y, (int)LevelManager.Instance.m_TileSize.X, (int)LevelManager.Instance.m_TileSize.Y);

                if (myFeet.Intersects(tileRect))
                {
                    Rectangle collRect = Rectangle.Intersect(myFeet, tileRect);
                    if (m_Velocity.Y >= 0.0)
                    {
                        m_Position.Y -= (collRect.Height - 1) * Math.Sign(m_Position.Y - other.m_Position.Y);
                        //m_Velocity.Y = 0.0f;
                        m_bIsHurt = false;
                        m_bJumping = false;
                        m_bIsOnLand = true;
                    }
                }
                else if (myRect.Intersects(tileRect))
                {
                    Rectangle collRect = Rectangle.Intersect(myRect, tileRect);
                    Vector2 Angle = new Vector2(myRect.Center.Y-tileRect.Center.Y, myRect.X-tileRect.X);
                    if (collRect.Width > collRect.Height && collRect.Width > 12)
                    {
                        m_Position.Y += (collRect.Height + 1) * Math.Sign(m_Position.Y - other.m_Position.Y);
                        if (m_Velocity.Y < 0.0f)
                            m_Velocity.Y = 0.0f;
                    }
                    else
                        m_Position.X += (collRect.Width + 1) * Math.Sign(m_Position.X - other.m_Position.X);
                }
            }
            else if (other.m_ObjectType == OBJ_TYPE.OBJ_PORTAL)
            {
                Rectangle myRect = new Rectangle((int)m_Position.X - 32, (int)m_Position.Y - 128, 64, 100);
                Rectangle portalRect = new Rectangle((int)other.m_Position.X-32, (int)other.m_Position.Y-32, 64, 64);

                if (myRect.Intersects(portalRect))
                {
                    if (((Portal)other).m_nTrigger == 0 ||
                        (((Portal)other).m_nTrigger == 1 && m_Direction == SpriteEffects.FlipHorizontally) ||
                        (((Portal)other).m_nTrigger == 2 && m_Direction == SpriteEffects.None))
                    {
                        LevelManager.Instance.Load(((Portal)other).m_szDestFile);
                        m_Position = ((Portal)other).m_DestPosition;
                        //m_Velocity = new Vector2(0.0f, 0.0f);
                    }

                }
            }
            else if (other.m_ObjectType == OBJ_TYPE.OBJ_ENEMY)
            {
                Rectangle myRect = new Rectangle((int)m_Position.X - 32, (int)m_Position.Y - 128, 64, 100);
                Rectangle enemyRect = new Rectangle((int)other.m_Position.X - (int)((Enemy)other).m_CollisionSize.X / 2, (int)other.m_Position.Y - (int)((Enemy)other).m_CollisionSize.Y, (int)((Enemy)other).m_CollisionSize.X, (int)((Enemy)other).m_CollisionSize.Y);

                if (myRect.Intersects(enemyRect) && m_fInvulnTimer <= 0.0f)
                {
                    m_Velocity = new Vector2(Math.Sign(m_Position.X - other.m_Position.X) * 30.0f, -60.0f);
                    m_Position += m_Velocity/10;
                    m_bIsHurt = true;
                    m_fInvulnTimer = 10.0f;
                    if (((Enemy)other).m_nStr > GCM.PlayerStat("Defense"))
                        GCM.PlayerStat("HP", GCM.PlayerStat("HP") - (((Enemy)other).m_nStr - GCM.PlayerStat("Defense")));
                    else
                        GCM.PlayerStat("HP", GCM.PlayerStat("HP") - 1);
                }
            }
        }

    }
}
